package com.xuecheng.content.service.jobHandler;

import com.xuecheng.base.exception.XueChengPlusException;
import com.xuecheng.content.feignClient.SearchServiceClient;
import com.xuecheng.content.mapper.CoursePublishMapper;
import com.xuecheng.content.model.dto.CourseIndex;
import com.xuecheng.content.model.po.CoursePublish;
import com.xuecheng.content.service.CoursePublishService;
import com.xuecheng.messagesdk.model.po.MqMessage;
import com.xuecheng.messagesdk.service.MessageProcessAbstract;
import com.xuecheng.messagesdk.service.MqMessageService;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import freemarker.template.TemplateException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * @Author xiao
 * @Date 2024/12/13 16:55
 * @ClassName: CoursePublishTask
 * @Description:
 */
@Slf4j
@Component
public class CoursePublishTask extends MessageProcessAbstract {

    public CoursePublishTask(MqMessageService mqMessageService, CoursePublishMapper coursePublishMapper, CoursePublishService coursePublishService, SearchServiceClient searchServiceClient) {
        super(mqMessageService);
        this.coursePublishService = coursePublishService;
        this.searchServiceClient = searchServiceClient;
    }

    private final CoursePublishService coursePublishService;
    private final SearchServiceClient searchServiceClient;

    //任务调度入口
    @XxlJob("CoursePublishJobHandler")
    public void coursePublishJobHandler() throws Exception {
        // 分片参数
        int shardIndex = XxlJobHelper.getShardIndex();
        int shardTotal = XxlJobHelper.getShardTotal();
        log.debug("shardIndex=" + shardIndex + ",shardTotal=" + shardTotal);
        //参数:分片序号、分片总数、消息类型、一次最多取到的任务数量、一次任务调度执行的超时时间
        process(shardIndex, shardTotal, "course_publish", 30, 60);
    }

    /**
     * @param mqMessage 执行任务内容
     * @return boolean true:处理成功，false处理失败
     * @description 任务处理
     * @author Mr.M
     * @date 2022/9/21 19:47
     */

    @Override
    public boolean execute(MqMessage mqMessage) {
        //任务执行逻辑
        //获取消息相关的业务信息
        String businessKey1 = mqMessage.getBusinessKey1();
        long courseId = Integer.parseInt(businessKey1);
        //1 课程静态化
        generateCourseHtml(mqMessage, courseId);
        //2 课程索引
        saveCourseIndex(mqMessage, courseId);
        //3 课程缓存
        saveCourseCache(mqMessage, courseId);
        return true;

    }

    //课程静态化
    private void generateCourseHtml(MqMessage mqMessage, long courseId) {
        log.debug("开始进行课程静态化,课程id:{}", courseId);
        Long id = mqMessage.getId(); //消息id
        //消息处理service
        MqMessageService mqMessageService = this.getMqMessageService();
        //消息幂等性判断
        int stageOne = mqMessageService.getStageOne(id);
        if (stageOne > 0) {
            log.info("课程静态化已完成,课程id:{}", courseId);
            return;
        }
        try {
            coursePublishService.generateHtmlByTemplate(courseId);
        } catch (Exception e) {
           log.error("课程静态化失败,课程id:{}",courseId,e);
           XueChengPlusException.cast("课程静态化失败");
        }

        //保存第一阶段状态
        mqMessageService.completedStageOne(id);

    }


    //保存课程索引信息
    public void saveCourseIndex(MqMessage mqMessage, long courseId) {
        log.debug("保存课程索引信息,课程id:{}", courseId);
        Long id = mqMessage.getId(); //取出消息id

        MqMessageService mqMessageService = this.getMqMessageService();//取出当前注入的mqMessageService
        //消息幂等性判断
        int stageTwo = mqMessageService.getStageTwo(id);
        if (stageTwo > 0) {
            log.info("课程索引已处理直接返回，课程id:{}", courseId);
            return;
        }
        //取出课程发布信息
        CoursePublish coursePublish = coursePublishService.getById(courseId);
        //拷贝至课程索引对象
        CourseIndex courseIndex = new CourseIndex();
        BeanUtils.copyProperties(coursePublish, courseIndex);
        //远程调用搜索服务api添加课程信息到索引
        Boolean b = searchServiceClient.add(courseIndex);
        if (!b) {
            XueChengPlusException.cast("添加索引失败");
        }
        //保存第一阶段状态
        mqMessageService.completedStageTwo(id);
    }


    //将课程信息缓存至redis
    public void saveCourseCache(MqMessage mqMessage, long courseId) {
        log.debug("将课程信息缓存至redis,课程id:{}", courseId);
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }


    }
}